﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace FotoAnotSharp.Anotator
{
    public partial class AnotationEditor : UserControl
    {
        public AnotationEditor()
        {
            InitializeComponent();
            annotanioPanel1.Editor = this;
        }

        void Clear()
        {
            Panel.SelectedPolygon = null;
            mPolygones.Clear();
            Background = null;
        }

        private int mNextId = 1;

        public AnotPolygon AddPolygon(PointF[] points)
        {
            return AddPolygon(points, mNextId++);
        }

        private AnotPolygon AddPolygon(PointF[] points, int id)
        {
            AnotPolygon polygon = new AnotPolygon(this, id);
            foreach (PointF p in points)
                polygon.AddPoint(p);
            mPolygones.Add(polygon.Id, polygon);

            if (PolygonCreated != null)
                PolygonCreated(this, polygon);

            return polygon;
        }

        public void RemovePolygon(AnotPolygon polygon)
        {
            mPolygones.Remove(polygon.Id);

            if (PolygonRemoved != null)
                PolygonRemoved(this, polygon);
        }

        public bool GetPolygon(int id, out AnotPolygon p)
        {
            return mPolygones.TryGetValue(id, out p);
        }

        public delegate void AnotPolygonDelegate(AnotationEditor sender, AnotPolygon polygon);
        public event AnotPolygonDelegate PolygonSelected;
        public void OnPolygonSelected(AnotPolygon selected)
        {
            if (PolygonSelected != null)
                PolygonSelected(this, selected);
        }

        public AnotPolygon SelectedPolygon
        {
            get { return Panel.SelectedPolygon; }
            set { Panel.SelectedPolygon = value; }
        }

        public event AnotPolygonDelegate PolygonCreated;
        public event AnotPolygonDelegate PolygonRemoved;

        private Dictionary<int, AnotPolygon> mPolygones = new Dictionary<int, AnotPolygon>();
        public IEnumerable<AnotPolygon> Polygons { get { return mPolygones.Values; } }

        public AnotationPanel Panel { get { return annotanioPanel1; } }

        public event AnotPolygonDelegate PolygonMoved;

        public void RaisePolygonMoved(AnotPolygon p)
        { if (PolygonMoved != null && p != null) PolygonMoved(this, p); }

        private void toolStripButtonAddPoylgon_Click(object sender, EventArgs e)
        {
            Panel.AddPolygon();
        }

        private void toolStripButtonZoomMinus_Click(object sender, EventArgs e)
        {
            Panel.ZoomScale(0.7f);
        }

        private void toolStripButtonZoomPlus_Click(object sender, EventArgs e)
        {
            Panel.ZoomScale(1.3f);
        }

        public Bitmap Background { get; private set; }

        private byte[] mBgImageBytes = null;

        void OpenBackground()
        {
            using (OpenFileDialog d = new OpenFileDialog())
            {
                if (d.ShowDialog() != DialogResult.OK)
                    return;

                try
                {
                    mBgImageBytes = File.ReadAllBytes(d.FileName);
                    using (MemoryStream str = new MemoryStream(mBgImageBytes))
                    {
                        Background = new Bitmap(Image.FromStream(str));
                    }
                }
                catch (Exception er)
                {
#if DEBUG
                    throw er;
#endif
                    MessageBox.Show("Nelze načíst pozadí", "Chyba", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    Background = null;
                }

                Panel.Invalidate();
            }
        }

        private void toolStripButtonNewBg_Click(object sender, EventArgs e)
        {
            OpenBackground();
        }

        private void toolStripButtonAutoFit_Click(object sender, EventArgs e)
        {
            Panel.Autofit();
        }

        public AnotFile GetSaveFile()
        {
            AnotFile file = new AnotFile();
            file.Polygons = mPolygones.Values.Select(t => new FilePolygon()
            {
                Points = t.Points.Select(p => p.Location).ToList(),
                ID = t.Id
            }).ToList();
            file.Background = mBgImageBytes;
            file.NextId = mNextId;
            return file;
        }

        public void LoadFile(AnotFile file)
        {
            Clear();

            mNextId = file.NextId;
            foreach (FilePolygon fp in file.Polygons)
            {
                AddPolygon(fp.Points.ToArray(), fp.ID);
            }

            if (file.Background != null)
            {
                mBgImageBytes = file.Background;
                using (MemoryStream str = new MemoryStream(mBgImageBytes))
                {
                    Background = new Bitmap(Image.FromStream(str));
                }
            }

            Panel.Autofit();
        }

    }
}
